/*****************************************************************************/
/*!	\file		MainClientDirect.c
 *	\brief		C Source code file for the Example IEC61850 Client using the YX-PIS
 *				This Client receives data for a CSWI, GGIO, Phase Measurement and a Curve Description Array
 *				via GOOSE and Reporting.
 *				The Client can Direct Operate the GGIO and use Select before Operate to control the CSWI which
 *				is and enhanced security control.
 * 
 *				Directly connect to the server without cid file
 *
 *	\par		Dalian Yunxing Tech Co., Ltd.
 *
 *				Dalian, China
 *				Phone   : +86 (411) 8825 4852
 *				Email   : yx@yunxing.tech
 */
/*****************************************************************************/

#if defined (__PARADIGM__)
#include <clib.h>	// BECK needs clib.h
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "IEC61850API.h"
#include "PIS10Callbacks.h"
#include "IEC61850Functions.h"
#include "PrintView.h"
#include "PIS10CreateServerClient.h"
#include "LocalData.h"
#include "ExampleTypes.h"
#include "UserInput.h"

#ifndef NO_SSL
#include <openssl/ssl.h>
#include <openssl/err.h>
#endif

#define	yx_str_equal(a, b)  ((a) && (b) && strcmp((a), (b)) == 0)

static char* s_cfgFile = NULL;
static IEC61850 s_iec61850 = NULL;

int main(int argc, char** argv)
{
	IEC61850_ErrorCode result = S_OK;

	IEC61850_Parameters params = { 0 };
	unsigned long int options = 0;

#ifndef NO_SSL
	SSL_library_init();
	OpenSSL_add_all_algorithms();
	SSL_load_error_strings();
#endif

	if (argc >= 2) {
		s_cfgFile = argv[1];
	}

	params.clientServerFlag = IEC61850_CLIENT;
	params.Ed1_Ed2_Flag = IEC61850_Edition2;
	params.options = options;
	params.fnUpdateCallback = (IEC61850_UpdateCallback)UpdateCallbackHandler;
	params.fnQuestionableCallback = (IEC61850_DataPointQuestionableCallback)QuestionableCallbackHandler;
	params.fnCmdTermCallback = (IEC61850_ControlCommandTerminationCallback)CommandTerminationCallback;
	// params.fnConnectionStatusCallback = (IEC61850_ConnectionStatusCallback)ConnectionStatusCallbackHandler;

	s_iec61850 = IEC61850_Create(&params, &result);
	if (result == S_OK) {
#if 1
		U32 aaIndex = 0;
		IEC61850_AssociationParameters assocParams = { 0 };
		strncpy(assocParams.IPAddress, "192.168.8.1", 16);
		// assocParams.port = 8102;
		result = IEC61850_ClientConnectDirect(s_iec61850, &assocParams, "client-direct", &aaIndex);
#else
		s_cfgFile = s_cfgFile ? s_cfgFile : "./mms-cid/client-direct.xml";
		result = IEC61850_ClientConnect(s_iec61850, s_cfgFile);
#endif
		if (result == S_OK) {
			IEC61850_SetOriginator(s_iec61850, NULL, ORCAT_BAY_CONTROL, NULL, 0);
			result = IEC61850_Start(s_iec61850);
			if (result != S_OK) {
				printf("   Can't start server: %s (%i)\n", IEC61850_ErrorString(result), result);
				IEC61850_Free(s_iec61850);
				return 1;
			}
		}

		SetMyServerClient(s_iec61850);

		do {
			char cmd[256] = { 0 };

			ClearScreen();
			printf("=================== IEC61850 Command Menu ===================\n");
			printf("[0] Connections\n");
			printf("[1] Report\n");
			printf("[2] Control\n");
			printf("[3] GOOSE SV\n");
			printf("[4] File\n");
			printf("[5] Log\n");
			printf("[6] SettingGroup\n");
			printf("[7] DataAccess\n");
			printf("[8] RPC\n");
			printf("[9] Discover-ASCI\n");
			printf("[a] Discover-AllDefinition\n");
			printf("[x] Quit\n");
			printf("=============================================================\n");
			printf("$");
			fflush(stdout);
			 
			if (fgets(cmd, sizeof(cmd), stdin) == NULL) {
				continue;
			}
			cmd[strlen(cmd) - 1] = '\0';

			if (yx_str_equal(cmd, "x")) {
				break;
			} else if (yx_str_equal(cmd, "0")) {
				GetConnectionsList();
			} else if (yx_str_equal(cmd, "1")) {
				ReportOperate();
			} else if (yx_str_equal(cmd, "2")) {
				ControlOperateDemo();
			} else if (yx_str_equal(cmd, "3")) {
				GooseSVOperate();
			} else if (yx_str_equal(cmd, "4")) {
				FileOperate();
			} else if (yx_str_equal(cmd, "5")) {
				LogOperate();
			} else if (yx_str_equal(cmd, "6")) {
				SettingGroupOperate();
			} else if (yx_str_equal(cmd, "7")) {
				DataAccess();
			} else if (yx_str_equal(cmd, "8")) {
				RPCAccess();
			} else if (yx_str_equal(cmd, "9")) {
				Discover(1);
			} else if (yx_str_equal(cmd, "a")) {
				Discover(2);
			}
		} while (1);
	} else {
		printf("   Client Failed to create: %s (%i)\n", IEC61850_ErrorString(result), result);
	}

	IEC61850_Free(s_iec61850);

	return 0;
}
